package top.xlq.mydb.backend.dm.pageCache;

import top.xlq.mydb.backend.dm.page.Page;
import top.xlq.mydb.backend.utils.Panic;
import top.xlq.mydb.common.Error;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

public interface PageCache {
    public static final int PAGE_SIZE = 1 << 13; // 每页8k大小

    int newPage(byte[] initData);

    Page getPage(int pgno) throws Exception;

    void close();

    void release(Page page);

    void truncateByBgno(int maxPgno);

    int getPageNumber();

    void flushPage(Page pg);

    public static PageCacheImpl create(String path, long memory) {
        File file = new File(path + PageCacheImpl.DB_SUFFIX);
        // 判断文件是否新创建
        try {
            if (!file.createNewFile()) {
                Panic.panic(Error.FileExistsException);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //判断是否可读
        if (!file.canRead() || !file.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }
        RandomAccessFile randomAccessFile = null;
        FileChannel fc = null;
        try {
            randomAccessFile = new RandomAccessFile(file,"rw");
            fc = randomAccessFile.getChannel();
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }

        return new PageCacheImpl(randomAccessFile,fc , (int) (memory / PageCache.PAGE_SIZE));
    }

    public static PageCacheImpl open(String path, long memory) {
        File file = new File(path + PageCacheImpl.DB_SUFFIX);

        if (!file.exists()) {
            Panic.panic(Error.FileNotExistsException);
        }
        //判断是否可读
        if (!file.canRead() && !file.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }

        RandomAccessFile randomAccessFile = null;
        FileChannel fc = null;
        try {
            randomAccessFile = new RandomAccessFile(file,"rw");
            fc = randomAccessFile.getChannel();
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }

        return new PageCacheImpl(randomAccessFile,fc , (int) (memory / PageCache.PAGE_SIZE));
    }
}
